package com.cy.ppj.service.user.impl;

import com.cy.ppj.comm.constant.Constants;
import com.cy.ppj.comm.utils.CommonUtils;
import com.cy.ppj.dao.mapper.account.AccountMapper;
import com.cy.ppj.dao.mapper.account.CommissionMapper;
import com.cy.ppj.dao.mapper.account.TeamCommissionMapper;
import com.cy.ppj.dao.mapper.city.CityMapper;
import com.cy.ppj.dao.mapper.company.CompanyMapper;
import com.cy.ppj.dao.mapper.company.CompanyMemberMapper;
import com.cy.ppj.dao.mapper.user.UserCityMapper;
import com.cy.ppj.dao.mapper.user.UserInfoMapper;
import com.cy.ppj.dao.mapper.user.UserMapper;
import com.cy.ppj.dao.mapper.user.UserRecommenderMapper;
import com.cy.ppj.model.PageBean;
import com.cy.ppj.model.Result;
import com.cy.ppj.model.domian.account.Account;
import com.cy.ppj.model.domian.account.Commission;
import com.cy.ppj.model.domian.account.TeamCommission;
import com.cy.ppj.model.domian.city.City;
import com.cy.ppj.model.domian.company.Company;
import com.cy.ppj.model.domian.company.CompanyMember;
import com.cy.ppj.model.domian.user.User;
import com.cy.ppj.model.domian.user.UserRecommender;
import com.cy.ppj.model.dto.recommender.UserRecommenderDTO;
import com.cy.ppj.model.dto.user.UserLoginDTO;
import com.cy.ppj.model.dto.user.UserAddDTO;
import com.cy.ppj.model.dto.user.UserImprotDTO;
import com.cy.ppj.model.enums.UserStatus;
import com.cy.ppj.model.enums.UserType;
import com.cy.ppj.model.enums.account.BrokerLevel;
import com.cy.ppj.model.query.ChannelUserByCompanyAdminQuery;
import com.cy.ppj.model.query.ChannelUserBySalesAdminQuery;
import com.cy.ppj.model.query.ChannelUserBySalesQuery;
import com.cy.ppj.model.query.UserAdminQuery;
import com.cy.ppj.model.vo.ChannelUserAdminVO;
import com.cy.ppj.model.vo.ChannelUserByCompanyAdminVO;
import com.cy.ppj.model.vo.ChannelUserBySalesAdminVO;
import com.cy.ppj.model.vo.ChannelUserBySalesVO;
import com.cy.ppj.model.vo.UserDetailAdminVO;
import com.cy.ppj.model.vo.SalesUserAdminVO;
import com.cy.ppj.model.vo.front.account.AccountIndexVO;
import com.cy.ppj.service.BaseService;
import com.cy.ppj.service.user.UserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Base64Utils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * @description: 用户
 * @author: Ocean
 * @create: 2018-07-19 20:23
 **/
@Service
public class UserServiceImpl extends BaseService implements UserService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Autowired
    private UserRecommenderMapper userRecommenderMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private AccountMapper accountMapper;
    @Autowired
    private CompanyMapper companyMapper;
    @Autowired
    private CompanyMemberMapper companyMemberMapper;
    @Autowired
    private UserCityMapper userCityMapper;
    @Autowired
    private CommissionMapper commissionMapper;
    @Autowired
    private TeamCommissionMapper teamCommissionMapper;
    @Autowired
    private CityMapper cityMapper;

    @Override
    @Transactional
    public void insertUser(UserAddDTO userAddDTO) {
        User dbUser = new User();
        dbUser.setMobile(userAddDTO.getMobile());
        dbUser = userMapper.selectOne(dbUser);
        state(dbUser == null, "该用户已存在");

        UserRecommenderDTO recommendUsers = null;
        //推荐人
        if (StringUtils.hasLength(userAddDTO.getRecommendCode())) {
            //如果有推荐码则添加推荐人
            String mobile = userAddDTO.getRecommendCode();
            if (mobile.length() != 11) {
                //如果推荐码大于11位，需要解密
                mobile = new String(Base64Utils.decodeFromString(mobile));
                state(StringUtils.hasLength(mobile), "推荐码异常");
            }
            //如果填写了推荐人手机号码，查询该用户
            recommendUsers = userRecommenderMapper.selectRecommenderRelationByMobile(mobile);
            //填写了并未查到时抛出异常
            state(recommendUsers != null, "推荐人（所属上级）信息异常");
        }
        Date createTime = new Date();

        //创建用户
        User user = new User();
        BeanUtils.copyProperties(userAddDTO, user);
        user.setNickName(StringUtils.isEmpty(userAddDTO.getNickName()) ? userAddDTO.getMobile() : userAddDTO.getNickName());
        user.setType(userAddDTO.getUserType());
        user.setRealAuth(false);
        user.setStatus(UserStatus.NORMAL);
        user.setLastReadProductNoticeTime(createTime);
        user.setLastReadPlatformAnnouncementTime(createTime);
        user.setCreateTime(createTime);
        user.setPassword(CommonUtils.md5Passwod(user.getPassword()));
        userMapper.insertSelective(user);

        //城市，如果城市ID不为空，则添加用户与城市的关联关系
//        if (!StringUtils.isEmpty(userAddDTO.getCityId())) {
//            UserCity userCity = new UserCity();
//            userCity.setCityId(userAddDTO.getCityId());
//            userCity.setUserId(user.getId());
//            userCity.setCreateTime(createTime);
//            userCityMapper.insertSelective(userCity);
//        }

        //公司
        if (UserType.CHANNEL.equals(userAddDTO.getUserType()) && StringUtils.hasLength(userAddDTO.getCompanyName())) {
            Company company = new Company();
            company.setName(userAddDTO.getCompanyName());
            company = companyMapper.selectOne(company);
            state(company != null, "查不到该公司");
            CompanyMember companyMember = new CompanyMember();
            companyMember.setUserId(user.getId());
            companyMember.setCompanyId(company.getId());
            companyMember.setCreateTime(createTime);
            companyMemberMapper.insertSelective(companyMember);
        }

        //创建用户账户
        Account account = new Account();
        account.setUserId(user.getId());
        account.setCreateTime(createTime);
        accountMapper.insertSelective(account);
        //添加推荐人信息
        if (recommendUsers != null) {
            //推荐关系建立
            UserRecommender recommender = new UserRecommender();
            recommender.setUserId(user.getId());
            recommender.setRecommendUserId(recommendUsers.getFirstUserRecommender());
            recommender.setCreateTime(createTime);
            recommender.setUpdateTime(createTime);
            userRecommenderMapper.insert(recommender);

            //团队一级佣金账户
            TeamCommission teamCommission = new TeamCommission();
            teamCommission.setUserId(recommendUsers.getFirstUserRecommender());
            teamCommission.setLevel(1);
            teamCommission.setMemberUserId(user.getId());
            teamCommission.setCreateTime(createTime);
            teamCommission.setUpdateTime(createTime);
            teamCommissionMapper.insertSelective(teamCommission);

            int result = commissionMapper.addMemberCount(recommendUsers.getFirstUserRecommender(), 1, 0);
            state(result == 1, "更新团队成员数量异常");
        }

        if (recommendUsers != null && recommendUsers.getSecondUserRecommender() != null) {
            //团队二级佣金账户
            TeamCommission teamCommission = new TeamCommission();
            teamCommission.setUserId(recommendUsers.getSecondUserRecommender());
            teamCommission.setLevel(2);
            teamCommission.setMemberUserId(user.getId());
            teamCommission.setCreateTime(createTime);
            teamCommission.setUpdateTime(createTime);
            teamCommissionMapper.insertSelective(teamCommission);

            int result = commissionMapper.addMemberCount(recommendUsers.getSecondUserRecommender(), 0, 1);
            state(result == 1, "更新团队成员数量异常");
        }

        //创建佣金账户
        Commission commission = new Commission();
        commission.setUserId(user.getId());
        commission.setCreateTime(createTime);
        commission.setUpdateTime(createTime);
        commissionMapper.insertSelective(commission);
    }

    @Override
    @Transactional
    public void insertUsers(List<UserImprotDTO> userImprotDTOList) {
        Date createTime = new Date();
        List<User> users = new ArrayList<>();
        userImprotDTOList.stream().forEach(u -> {
            //设置用户默认信息
            User user = new User();
            user.setMobile(u.getMobile());
            user.setCreateTime(createTime);
            user.setType(u.getUserType());
            user.setStatus(UserStatus.INITIAL);
            String password = CommonUtils.randomNumber(6);
            user.setPassword(CommonUtils.md5Passwod(password));
            users.add(user);
        });
        //批量导入
        userMapper.insertBatch(users);
    }

    @Override
    public Result login(String mobile, String password) {

        password = CommonUtils.md5Passwod(password);

        UserLoginDTO user = userMapper.login(mobile, password);

        return doLogin(user);
    }


    @Override
    public Result loginByWecaht(String openId) {

        UserLoginDTO user = userMapper.loginByWechat(openId);

        return doLogin(user);
    }

    /**
     * 登录操作
     *
     * @param user
     * @return
     */
    private Result doLogin(UserLoginDTO user) {

        if (user == null) {
            return Result.fail("请输入正确的账号或密码");
        }
        
        if(user.getCityId() != null) {
        	City city = cityMapper.selectByPrimaryKey(user.getCityId());
        	if(city != null) {
        		city.setStatus(null);
        		city.setCreateTime(null);
        		city.setUpdateTime(null);
        		user.setCity(city);
        	}
        }

        switch (user.getStatus()) {
            case INITIAL:
                return Result.fail("首次登录，请修改密码！");

            case DELETE:
                return Result.fail("不存在该账户");

            case LOCKED:
                return Result.fail("该账户已锁定，请联系客服");

            default:
                break;
        }

        //生成随机码
        String token = UUID.randomUUID().toString();
        String key = Constants.USER_LOGIN_KEY.concat(token);
        user.setToken(token);
        //把用户登录信息存入redis
        redisTemplate.opsForValue().set(key, user, Constants.LOGIN_TIME, Constants.LOGIN_TIME_UNIT);
        return Result.success("登录成功", user);
    }

    @Override
    @Transactional
    public Result bindSalesman(String mobile, Long userId) {
        // 根据手机号码查出要绑定的业务员id
        User salesmanUser = new User();
        salesmanUser.setMobile(mobile);
        salesmanUser = userMapper.selectOne(salesmanUser);
        state(salesmanUser != null, "该业务员不存在");
        if (!UserType.SALES.equals(salesmanUser.getType())) {
            return Result.fail("输入的用户不是业务员角色");
        }
        UserRecommender ur = new UserRecommender();
        ur.setUserId(userId);
        ur.setRecommendUserId(salesmanUser.getId());
        Date createTime = new Date();
        ur.setCreateTime(createTime);
        ur.setUpdateTime(createTime);
        userRecommenderMapper.insertSelective(ur);
        return Result.success("绑定成功");
    }

    @Override
    public PageBean<ChannelUserAdminVO> queryChannelUserList(UserAdminQuery query) {
        if (query.getRegisterStartTime() != null) {
            query.setRegisterStartTime(CommonUtils.getDayStartTime(query.getRegisterStartTime()));
        }
        if (query.getRegisterEndTime() != null) {
            query.setRegisterEndTime(CommonUtils.getDayEndTime(query.getRegisterEndTime()));
        }
        int total = userMapper.queryChannelUserListCount(query);
        List<ChannelUserAdminVO> list = new ArrayList<>();
        if (total > 0) {
            query.startPage();
            list = userMapper.queryChannelUserList(query);
            list.stream().forEach(u -> {
            	if(!CommonUtils.isEmpty(u.getLevel())) {
            		u.setLevelText(u.getLevel().getText());
            	}
            });
        }
        return new PageBean<>(list, total);
    }

    @Override
    public UserDetailAdminVO queryUserDetailAdmin(Long userId) {
        UserDetailAdminVO cudVo = userMapper.queryUserDetailAdmin(userId);
        state(cudVo != null, "该用户不存在");
        return cudVo;
    }

    @Override
    public PageBean<SalesUserAdminVO> querySalesUserList(UserAdminQuery userAdminQuery) {
        if (userAdminQuery.getRegisterStartTime() != null) {
            userAdminQuery.setRegisterStartTime(CommonUtils.getDayStartTime(userAdminQuery.getRegisterStartTime()));
        }
        if (userAdminQuery.getRegisterEndTime() != null) {
            userAdminQuery.setRegisterEndTime(CommonUtils.getDayEndTime(userAdminQuery.getRegisterEndTime()));
        }
        int total = userMapper.querySalesUserListCount(userAdminQuery);
        List<SalesUserAdminVO> list = new ArrayList<>();
        if (total > 0) {
            userAdminQuery.startPage();
            list = userMapper.querySalesUserList(userAdminQuery);
            list.stream().forEach(u -> {
            	if(!CommonUtils.isEmpty(u.getLevel())) {
            		u.setLevelRemark(u.getLevel().getText());
            	}
            });
        }
        return new PageBean<>(list, total);
    }

    @Override
    @Transactional
    public Result updateUserStatus(Long userId, UserStatus status) {
        User user = new User();
        user.setId(userId);
        user.setStatus(status);
        user.setUpdateTime(new Date());
        int result = userMapper.updateByPrimaryKeySelective(user);
        state(result == 1, "修改用户状态失败");
        return Result.success("修改成功");
    }

    @Override
    public PageBean<ChannelUserBySalesAdminVO> queryChannelUserBySalesAdmin(ChannelUserBySalesAdminQuery query) {
        int total = userMapper.queryChannelUserBySalesAdminCount(query);
        List<ChannelUserBySalesAdminVO> list = new ArrayList<>();
        if (total > 0) {
            query.startPage();
            list = userMapper.queryChannelUserBySalesAdmin(query);
        }
        return new PageBean<>(list, total);
    }

    @Override
    @Transactional
    public void updatePassword(Long userId, String oldPassword, String newPassword) {
        String md5OldPassword = CommonUtils.md5Passwod(oldPassword);
        String md5NewPassword = CommonUtils.md5Passwod(newPassword);
        User dbUser = new User();
        dbUser.setId(userId);
        dbUser.setPassword(md5OldPassword);
        dbUser = userMapper.selectOne(dbUser);
        state(dbUser != null, "旧密码不正确");
        User user = new User();
        user.setId(userId);
        user.setPassword(md5NewPassword);
        user.setUpdateTime(new Date());
        userMapper.updateByPrimaryKeySelective(user);
    }

    @Override
    @Transactional
    public void resetPassword(String mobile, String newPassword) {
        User dbUser = new User();
        dbUser.setMobile(mobile);
        dbUser = userMapper.selectOne(dbUser);
        state(dbUser != null, "用户不存在");
        String md5NewPassword = CommonUtils.md5Passwod(newPassword);
        User user = new User();
        user.setId(dbUser.getId());
        user.setPassword(md5NewPassword);
        user.setUpdateTime(new Date());
        userMapper.updateByPrimaryKeySelective(user);
    }

    @Override
    public PageBean<ChannelUserBySalesVO> queryChannelUserBySales(ChannelUserBySalesQuery channelUserBySalesQuery) {
        int total = userMapper.queryChannelUserBySalesCount(channelUserBySalesQuery);
        List<ChannelUserBySalesVO> list = new ArrayList<>();
        if (total > 0) {
            channelUserBySalesQuery.startPage();
            list = userMapper.queryChannelUserBySales(channelUserBySalesQuery);
        }
        return new PageBean<>(list, total);
    }

    @Override
    public PageBean<ChannelUserByCompanyAdminVO> queryChannelUserByCompanyAdmin(ChannelUserByCompanyAdminQuery query) {
        int total = userMapper.queryChannelUserByCompanyAdminCount(query);
        List<ChannelUserByCompanyAdminVO> list = new ArrayList<>();
        if (total > 0) {
            query.startPage();
            list = userMapper.queryChannelUserByCompanyAdmin(query);
        }
        return new PageBean<>(list, total);
    }

    @Override
    @Transactional
    public void unBindBank(Long userId) {
        int result = userInfoMapper.unBindBank(userId);
        state(result == 1, "解绑银行卡失败");
    }

    @Override
    public User selectUser(User user) {
        user = userMapper.selectOne(user);
        state(user != null, "该用户不存在");
        return user;
    }

    @Override
    public AccountIndexVO queryAccountIndexInfo(Long userId) {
        AccountIndexVO accountIndex = userMapper.selectAccountIndexInfo(userId);
        if (accountIndex != null) {
            //accountIndex.setTaemCount(accountIndex.getTaemFirstCount() + accountIndex.getTaemSecondCount());
            accountIndex.setLevelText(accountIndex.getLevel() != null ? accountIndex.getLevel().getText() : null);
            accountIndex.setBankCard(CommonUtils.bankCardFormat(accountIndex.getBankCard(), 4));
//            if(accountIndex.getNewUser() != null && accountIndex.getNewUser()) {
//            	accountIndex.setLevel(BrokerLevel.DIAMOND);
//            	accountIndex.setLevelText(BrokerLevel.DIAMOND.getText() + "（体验）");
//            }
            int taemAllCount = userRecommenderMapper.selectCountByRecommendUserIdAndLevel(userId, null);
            accountIndex.setTaemAllCount(taemAllCount);
        }
        return accountIndex;
    }

	@Override
	@Transactional
	public void updateUser(User user) {
		user.setUpdateTime(new Date());
		userMapper.updateByPrimaryKeySelective(user);
	}


}
